package com.anjiplus.template.gaea.business.modules.websocket.service;

import com.anji.plus.gaea.bean.ResponseBean;
import com.anji.plus.gaea.code.ResponseCode;
import com.anjiplus.template.gaea.business.util.ErpUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;



@ServerEndpoint(value = "/ws/{userIp}")
@Component
public class WebSocketServer {

    @PostConstruct
    public void init() throws Exception {
        WebSocketServer.maxConnectionLimit =  Integer.parseInt(websocketConnectionLimit == null? "3" : erpUtil.decode(websocketConnectionLimit));
        System.out.println("websocket 加载");
    }
    static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
    /**静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。*/
    private static int onlineCount = 0;
    /**concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。*/
    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
    private static Vector<String> userList = new Vector<>();
    /**与某个客户端的连接会话，需要通过它来给客户端发送数据*/
    private Session session;
    /**接收userIp*/
    private String userIp="";

    @Value("${customer.websocket-connection-limit:''}")
    private String websocketConnectionLimit;

    private static int maxConnectionLimit;

    private ErpUtil erpUtil = new ErpUtil();

    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session,@PathParam("userIp") String userIp) {
        this.session = session;
        this.userIp = userIp;


        if(webSocketMap.containsKey(userIp)){
            webSocketMap.remove(userIp);
            webSocketMap.put(userIp,this);
            //加入set中
        }else{
            try {
                if(maxConnectionLimit <= onlineCount){
                    sendMessage("maxConnectionLimit");
                    session.close();
                    return;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            userList.add(userIp);
            webSocketMap.put(userIp,this);
            //加入set中
            addOnlineCount();
            //在线数加1
        }

        log.info("用户连接:"+userIp+",当前在线人数为:" + getOnlineCount());
        sendMessage("initSuccess");

    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(CloseReason reason) {
        if(webSocketMap.containsKey(userIp)){
            webSocketMap.remove(userIp);
            userList.remove(userIp);
            //从set中删除
            subOnlineCount();
        }
        log.info("用户退出:"+userIp+",当前在线人数为:" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("用户消息:"+userIp+",报文:"+message);
        //可以群发消息
        //消息保存到数据库、redis
        if(StringUtils.isNotBlank(message)){
            try {
                if("heartBeat".equals(message)){
                    session.getBasicRemote().sendText("heartBeat");
                    return;
                }
//                //解析发送的报文
//                JSONObject jsonObject = JSON.parseObject(message);
//                //追加发送人(防止串改)
//                jsonObject.put("fromuserIp",this.userIp);
//                String touserIp=jsonObject.getString("touserIp");
//                //传送给对应touserIp用户的websocket
//                if(StringUtils.isNotBlank(touserIp)&&webSocketMap.containsKey(touserIp)){
//                    webSocketMap.get(touserIp).sendMessage(jsonObject.toJSONString());
//                }else{
//                    log.error("请求的userIp:"+touserIp+"不在该服务器上");
//                    //否则不在这个服务器上，发送到mysql或者redis
//                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误:"+this.userIp+",原因:"+error.getMessage());
        error.printStackTrace();
    }
    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message)  {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            log.error("发送消息失败：" + userIp  + " ---- " + message);
            e.printStackTrace();
        }
    }
    /**
     * 发送自定义消息
     * */
    public static ResponseBean sendInfo(String userIp, Map<String,Object> dataObj) throws IOException {
        log.info("发送消息到:"+userIp+"，报文:"+ dataObj.toString());
        if(StringUtils.isNotBlank(userIp)&&webSocketMap.containsKey(userIp)){
            webSocketMap.get(userIp).sendMessage(JSON.toJSONString(dataObj));
            return  ResponseBean.builder().data("发送成功").build();
        }else{
            String msg = "用户"+userIp+",不在线！";
            log.error(msg);
            return  ResponseBean.builder().code(ResponseCode.FAIL_CODE).message(msg).build();
        }
    }

    public static synchronized Vector<String> getUserList() {
        return userList;
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }

}
